<template>
    <div class="dropdown" :class="{ 'is-disabled': disabled }">
      <!-- q3123123 -->
      <div
        class="dropdown-trigger"
        @click="toggleDropdown"
        :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
      >
        <span v-if="!multiple">{{ selectedLabel }}</span>
        <span v-else>
          <span v-for="(item, index) in selectedItems" :key="index" class="selected-item">
            {{ getLabel(item) }}
            <i class="fa-solid fa-xmark" @click.stop="removeSelectedItem(item)" v-if="multiple"></i>
          </span>
        </span>
        <i
          class="fa-solid fa-chevron-down"
          :class="{ 'is-open': isOpen }"
        ></i>
        <i
          class="fa-solid fa-xmark clear-icon"
          @click.stop="clearSelection"
          v-if="selectedItems.length > 0 &&!disabled"
        ></i>
      </div>
      <div class="dropdown-menu" v-if="isOpen">
        <input
          v-model="searchQuery"
          @input="handleSearch"
          type="text"
          placeholder="搜索..."
          class="search-input"
        />
        <ul class="dropdown-list">
          <li
            v-for="item in filteredOptions"
            :key="getKey(item)"
            @click="selectItem(item)"
            :class="{ 'is-selected': isSelected(item) }"
          >
            <slot :item="item">{{ getLabel(item) }}</slot>
          </li>
        </ul>
      </div>
    </div>
  </template>
  
  <script setup name="Down">
  import { ref, computed, watch } from 'vue';
  
  const props = defineProps({
    options: {
      type: Array,
      default: () => []
    },
    multiple: {
      type: Boolean,
      default: false
    },
    modelValue: {
      type: [Array, Object, null],
      default: null
    },
    labelKey: {
      type: String,
      default: 'label'
    },
    valueKey: {
      type: String,
      default: 'value'
    },
    remoteSearch: {
      type: Function,
      default: null
    },
    disabled: {
      type: Boolean,
      default: false
    }
  });
  
  const emit = defineEmits(['update:modelValue']);
  
  const isOpen = ref(false);
  const searchQuery = ref('');
  const selectedItems = ref(props.multiple ? [...props.modelValue] : [props.modelValue].filter(Boolean));
  
  const filteredOptions = computed(() => {
    if (!searchQuery.value) {
      return props.options;
    }
    if (props.remoteSearch) {
      return [];
    }
    return props.options.filter(item =>
      getLabel(item).toLowerCase().includes(searchQuery.value.toLowerCase())
    );
  });
  
  const selectedLabel = computed(() => {
    if (selectedItems.value.length === 0) {
      return '';
    }
    return getLabel(selectedItems.value[0]);
  });
  
  const getLabel = (item) => {
    return item[props.labelKey] || item;
  };
  
  const getKey = (item) => {
    return item[props.valueKey] || item;
  };
  
  const isSelected = (item) => {
    return selectedItems.value.some(selected => getKey(selected) === getKey(item));
  };
  
  const toggleDropdown = () => {
    if (!props.disabled) {
      isOpen.value = !isOpen.value;
    }
  };
  
  const selectItem = (item) => {
    if (props.disabled) return;
    if (props.multiple) {
      if (isSelected(item)) {
        selectedItems.value = selectedItems.value.filter(selected => getKey(selected) !== getKey(item));
      } else {
        selectedItems.value.push(item);
      }
    } else {
      selectedItems.value = [item];
      isOpen.value = false;
    }
    emit('update:modelValue', props.multiple ? selectedItems.value : selectedItems.value[0]);
  };
  
  const clearSelection = () => {
    if (props.disabled) return;
    selectedItems.value = [];
    emit('update:modelValue', props.multiple ? [] : null);
  };
  
  const removeSelectedItem = (item) => {
    if (props.disabled) return;
    selectedItems.value = selectedItems.value.filter(selected => getKey(selected) !== getKey(item));
    emit('update:modelValue', props.multiple ? selectedItems.value : selectedItems.value[0]);
  };
  
  const handleSearch = async () => {
    if (props.remoteSearch) {
      const newOptions = await props.remoteSearch(searchQuery.value);
      // 假设 remoteSearch 返回一个新的选项数组
      // 这里简单替换原有的 options
      // 在实际应用中，可能需要更复杂的逻辑来更新选项
      // 比如合并新老选项等
      // 此处为了简化，直接替换
      props.options = newOptions; 
    }
  };
  
  watch(
    () => props.modelValue,
    (newValue) => {
      selectedItems.value = props.multiple ? [...newValue] : [newValue].filter(Boolean);
    },
    { deep: true }
  );
  </script>
  
  <style scoped>
  .dropdown {
    position: relative;
    width: 200px;
  }
  
  .dropdown-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    border: 1px solid #ccc;
    border-radius: 4px;
    cursor: pointer;
  }
  
  .dropdown-menu {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    max-height: 200px;
    overflow-y: auto;
    border: 1px solid #ccc;
    border-top: none;
    border-radius: 0 0 4px 4px;
    background-color: #fff;
    z-index: 10;
  }
  
  .search-input {
    width: 100%;
    padding: 8px 12px;
    border: none;
    border-bottom: 1px solid #ccc;
    outline: none;
  }
  
  .dropdown-list {
    list-style: none;
    padding: 0;
    margin: 0;
  }
  
  .dropdown-list li {
    padding: 8px 12px;
    cursor: pointer;
  }
  
  .dropdown-list li.is-selected {
    background-color: #f0f0f0;
  }
  
  .clear-icon {
    margin-left: 8px;
    cursor: pointer;
  }
  
  .is-disabled .dropdown-trigger {
    background-color: #f0f0f0;
    cursor: not-allowed;
  }
  
  .selected-item {
    display: inline-flex;
    align-items: center;
    background-color: #e0e0e0;
    padding: 2px 6px;
    margin-right: 4px;
    border-radius: 4px;
  }
  
  .selected-item i {
    margin-left: 4px;
    cursor: pointer;
  }
  </style>    